package com.hq.ims.platform.busservice;

import com.hq.authority.utils.AppUtils;
import com.hq.ims.data.entity.*;
import com.hq.ims.data.entityenum.*;
import com.hq.ims.data.event.BusInfoNotificationEvent;
import com.hq.ims.data.event.BusinfoEvent;
import com.hq.ims.data.service.*;
import com.hq.ims.data.utils.ErrMsgConstant;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.ims.data.vo.BusiInfoMapstruct;
import com.hq.utils.util.BooleanUtils;
import com.hq.utils.util.ObjectUtils;
import com.hq.utils.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author yinzhangxiao
 * @date 2024/10/25 17:06
 * @ClassName PlatformBusiInfoService
 **/
@Service
@Transactional(rollbackFor = Exception.class)
public class PlatformBusiInfoService {

    @Resource
    private BaseBusInfoNotificationService baseBusInfoNotificationService;
    @Resource
    private BaseBusiChangeTimeRecordService baseBusiChangeTimeRecordService;
    @Resource
    private BaseBusiIndustryCompanyService baseBusiIndustryCompanyService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private BaseBusiChangeService baseBusiChangeService;
    @Resource
    private BaseBusiInfoService baseBusiInfoService;

    /**
     * @description: 平台审核经营信息
     * @author: yinzhangxiao
     * @date: 2024/11/15 14:32
     */
    @Transactional(rollbackFor = Exception.class)
    public void audit(BusiInfoMapstruct.SaveVo vo) {
        Boolean emptyId = ObjectUtils.isNull(vo) || StringUtils.isEmpty(vo.getBusiInfoId()) || ObjectUtils.isNull(vo.getAuditStatus());
        BooleanUtils.isTrueThrow(emptyId, ErrMsgConstant.PROJECT_INFO_NOT_EXITS);
        //审核拒绝，原因不能为空
        Boolean remarkFlag = EnumAuditStatus.NotPass.getCode() == vo.getAuditStatus().getCode() && StringUtils.isEmpty(vo.getAuditRemark());
        BooleanUtils.isTrueThrow(remarkFlag, ErrMsgConstant.PROJECT_INFO_AUDIT_REMARK_NOT_EMPTY);
        //验证数据是否存在
        BusiInfo entity = baseBusiInfoService.getById(vo.getBusiInfoId());
        ObjectUtils.isNullThrow(entity, ErrMsgConstant.PROJECT_INFO_NOT_EXITS);
        //验证数据状态
        EnumAuditStatus.isCanAuditTh(entity.getAuditStatus());
        entity.setAuditStatus(vo.getAuditStatus());
        entity.setAuditTime(LocalDateTime.now());
        entity.setAuditUserId(AppUtils.getUserId());
        entity.setAuditRemark(vo.getAuditRemark());
        vo.setProvinceCode(entity.getProvinceCode());
        vo.setCityCode(entity.getCityCode());
        if (EnumAuditStatus.Pass.getCode() == vo.getAuditStatus().getCode()) {
            entity.setPublishTime(LocalDateTime.now());
            entity.setPublishStatus(EnumPublishStatus.Released);
            //比较变更数据
            BusiInfoMapstruct.SaveVo oldSaveVo = new BusiInfoMapstruct.SaveVo();
            BeanUtils.copyProperties(entity,oldSaveVo);
            List<Map<String, Object>> maps = baseBusiInfoService.compareFields(oldSaveVo, vo);
            baseBusiInfoService.compareIndustry(vo,maps);
            if (CollectionUtils.isNotEmpty(maps)){
                List<BusiChange> changeList = new ArrayList<>(maps.size());
                maps.forEach(map->{
                    BusiChange busiChange = new BusiChange();
                    busiChange.setBusiInfoId(vo.getBusiInfoId());
                    busiChange.setChangeContent(MapUtils.getString(map,"name"));
                    busiChange.setChangeBefore(MapUtils.getString(map,"changeBefore"));
                    busiChange.setChangeAfter(MapUtils.getString(map,"changeAfter"));
                    busiChange.setChangeTime(LocalDateTime.now());
                    busiChange.setChangeWay(EnumChangeWay.UserChange);
                    changeList.add(busiChange);
                });
                baseBusiChangeService.saveBatch(changeList);
            }
            //保存产业标记指派以及补全并保存产业标记公司
            baseBusiInfoService.saveBusiIndustryAssignList(vo);
            //推送经营信息到指定公司
            if (CollectionUtils.isNotEmpty(vo.getBusiIndustryAssignList())) {
                List<BusInfoNotification> notificationList = new ArrayList<>(vo.getBusiIndustryAssignList().size());
                vo.getBusiIndustryAssignList().forEach(
                        item -> item.getBusiIndustryCompanyList().forEach(
                                company -> {
                                    BusInfoNotification busInfoNotification = new BusInfoNotification();
                                    busInfoNotification.setBusiInfoId(entity.getBusiInfoId());
                                    busInfoNotification.setIndustryMarkId(company.getIndustryId());
                                    busInfoNotification.setIndustryMarkName(company.getIndustryName());
                                    busInfoNotification.setCompanyId(company.getCompanyId());
                                    busInfoNotification.setCompanyName(company.getCompanyName());
                                    busInfoNotification.setOrgId(entity.getOrgId());
                                    busInfoNotification.setPushDate(LocalDateTime.now());
                                    busInfoNotification.setReceiveStatus(EnumReceiveStatus.UnReceive);
                                    busInfoNotification.setNotificationWay(company.getNotificationWay());
                                    notificationList.add(busInfoNotification);
                                }
                        ));
                baseBusInfoNotificationService.saveBatch(notificationList);
                for (BusInfoNotification busInfoNotification : notificationList) {
                    //推到公司事件
                    applicationContext.publishEvent(new BusInfoNotificationEvent(this, busInfoNotification, BusInfoNotificationEvent.PUSH_TO_COMPANY));
                }
            }
        }else if(EnumAuditStatus.NotPass.getCode() == vo.getAuditStatus().getCode()){
            //驳回删除系统生成指派公司
            baseBusiIndustryCompanyService.lambdaUpdate()
                    .eq(BusiIndustryCompany::getBusiInfoId,vo.getBusiInfoId())
                    .eq(BusiIndustryCompany::getNotificationWay, EnumNotificationWay.Sysgenerated)
                    .remove();
        }
        //修改变更记录表变更状态
        BusiChangeTimeRecord busiChangeTimeRecord = baseBusiChangeTimeRecordService.lambdaQuery()
                .eq(BusiChangeTimeRecord::getBusiInfoId, vo.getBusiInfoId())
                .orderByDesc(BusiChangeTimeRecord::getChangeTime)
                .last(LocalConstant.LIMIT_1)
                .one();
        if (busiChangeTimeRecord != null) {
            busiChangeTimeRecord.setAuditStatus(vo.getAuditStatus());
            baseBusiChangeTimeRecordService.updateById(busiChangeTimeRecord);
        }
        baseBusiInfoService.updateById(entity);

        //发送事件
        //获取最新的经营信息
        BusiInfo lastBusiInfoData = baseBusiInfoService.getById(vo.getBusiInfoId());
        if (EnumAuditStatus.Pass.getCode() == vo.getAuditStatus().getCode()) {
            applicationContext.publishEvent(new BusinfoEvent(this, lastBusiInfoData, BusinfoEvent.PLATFORM_AUDIT_PASS_EVENT));
        } else {
            applicationContext.publishEvent(new BusinfoEvent(this, lastBusiInfoData, BusinfoEvent.PLATFORM_AUDIT_NOT_PASS_EVENT));
        }
    }

    /**
     * @description: 平台端查看源数据
     * @author: yinzhangxiao
     * @date: 2024/11/15 14:32
     */
    public BusiInfoMapstruct.BusiInfoVo getRootData(String parentId) {
        BusiInfo parentBusiInfo = baseBusiInfoService.getById(parentId);
        ObjectUtils.isNullThrow(parentBusiInfo, ErrMsgConstant.PROJECT_INFO_NOT_EXITS);
        BusiInfoMapstruct.BusiInfoVo busiInfoVo = BusiInfoMapstruct.INSTANCE.toBusiInfoVo(parentBusiInfo);
        List<BusiInfo> list = baseBusiInfoService.lambdaQuery()
                .eq(BusiInfo::getParentId, parentBusiInfo.getBusiInfoId())
                .list();
        busiInfoVo.setDerivativeList(list);
        return busiInfoVo;
    }


}
